package tools;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.util.*;

/**
 * yaml config file convert to properties config file
 * Created by james.you on 2018/5/14.
 */
public class Yaml2PROPS {
    private final static Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    /**
     * convert yaml 2 properties
     *
     * @param yamlInputStream yaml file inputStream
     * @param envTags array of names that will be used to extracted to *.properties, ex: dev, prod, staging...
     * @return Properties
     * */
    public static Properties fromYamlInputStream(InputStream yamlInputStream,List<String> envTags)throws IOException{
        Yaml yaml = new Yaml();
        Map<String, Object> map = (Map<String, Object>) yaml.load(yamlInputStream);
        Properties properties = new Properties() {
            @Override
            public synchronized Enumeration<Object> keys() {
                return Collections.enumeration(new TreeSet<Object>(super.keySet()));
            }
        };
        for (String entryName : envTags) {
            if (StringUtils.isEmpty(entryName)) {
                continue;
            }
            Map<String, Object> entry = (Map<String, Object>) map.get(entryName);
            iterateAndProcess(properties, entry, "");
        }
        //properties.store(new FileOutputStream(new File(destProp)), "Generated by Yml2Props");//如果需要保存到文件
        return properties;
    }

    /**
     * convert yaml 2 properties
     *
     * @param yamlFilePath yaml file Path
     * @param envTags array of names that will be used to extracted to *.properties, ex: dev, prod, staging...
     * @return Properties
     * */
    public static Properties fromYamlFile(String yamlFilePath,List<String> envTags) throws IOException{
        InputStream yamlInputStream = new FileInputStream(new File(yamlFilePath));
        return fromYamlInputStream(yamlInputStream,envTags);
    }

    /**
     * Iterate yaml entry and push values into properties
     * @param properties
     * @param ymlEntry
     * @param rootKey
     * @return
     */
    private static void iterateAndProcess(Properties properties, Map<String, Object> ymlEntry, String rootKey) {
        for (String key : ymlEntry.keySet()) {
            Object value = ymlEntry.get(key);
            if (value instanceof Map) {
                iterateAndProcess(properties, (Map<String, Object>) value, StringUtils.isEmpty(rootKey) ? key : rootKey
                        + "." + key);
            }
            else {
                properties.setProperty(StringUtils.isEmpty(rootKey) ? key : rootKey + "." + key, value.toString());
            }
        }
    }
}
